import { Subject } from 'rxjs';
import { defineComponent } from 'vue';
import { Util, throttle } from 'ibz-core';

const AppDataPickerProps = {
  /**
   * 双向绑定值
   * @type {string}
   * @memberof AppDataPickerProps
   */
  value: {
    type: String,
  },

  /**
   * 是否禁用
   * @type {boolean}
   * @memberof AppDataPickerProps
   */
  disabled: Boolean,

  /**
   * 上下文
   *
   * @type {Object}
   * @memberof AppDataPickerProps
   */
  context: Object,

  /**
   * 视图参数
   *
   * @type {Object}
   * @memberof AppDataPickerProps
   */
  viewParam: Object,

  /**
   * 应用实体主信息属性名称
   *
   * @type {string}
   * @memberof AppDataPickerProps
   */
  deMajorField: {
    type: String,
    default: 'srfmajortext',
  },

  /**
   * 应用实体主键属性名称
   *
   * @type {string}
   * @memberof AppDataPickerProps
   */
  deKeyField: {
    type: String,
    default: 'srfkey',
  },

  /**
   * 上下文data数据（表单数据）
   *
   * @type {*}
   * @memberof AppDataPickerProps
   */
  contextData: {
    type: Object,
    default: {},
  },

  /**
   * 属性项名称
   *
   * @type {string}
   * @memberof AppDataPickerProps
   */
  name: {
    type: String,
  },

  /**
   * 选择视图
   *
   * @type {*}
   * @memberof AppDataPickerProps
   */
  pickUpView: {
    type: Object,
  },

  /**
   * 数据链接参数
   *
   * @type {*}
   * @memberof AppDataPickerProps
   */
  linkView: {
    type: Object,
  },

  /**
   * 值项名称
   *
   * @type {string}
   * @memberof AppDataPickerProps
   */
  valueItem: {
    type: String,
  },

  /**
   * 局部上下文参数
   *
   * @type {Object}
   * @memberof AppDataPickerProps
   */
  localContext: Object,

  /**
   * 局部导航参数
   *
   * @type {Object}
   * @memberof AppDataPickerProps
   */
  localParam: Object,

  /**
   * 下拉视图宽度
   *
   * @type {String}
   * @memberof AppDataPickerProps
   */
  dropdownViewWidght: String,

  /**
   * 下拉视图高度
   *
   * @type {String}
   * @memberof AppDataPickerProps
   */
  dropdownViewHeight: String,

  /**
   * 只读模式
   * @type {boolean}
   * @memberof AppDataPickerProps
   */
  readonly: Boolean,

  /**
   * placeholder值
   * @type {String}
   * @memberof AppDataPickerProps
   */
  placeholder: String,

  /**
   * 模型服务
   * @type {Object}
   * @memberof AppDataPickerProps
   */
  modelService: Object,
};

/**
 * 数据选择编辑器
 *
 * @class AppDataPicker
 */
export const AppDataPicker = defineComponent({
  name: 'AppDataPicker',
  props: AppDataPickerProps,
  emits: ['editorValueChange'],
  computed: {
    /**
     * 当前选中数据集
     *
     * @returns any[]
     * @memberof AppDataPicker
     */
    curValue() {
      let values: any[] = [];
      let valueItems: any[] = [];
      const curValue: any[] = [];
      if (this.name && this.valueItem) {
        values = this.contextData[this.name]?.split(',');
        valueItems = this.contextData[this.valueItem]?.split(',');
      }
      if (values?.length > 0 && values?.length == valueItems?.length) {
        values.forEach((value: string, index: number) => {
          curValue.push({ [this.deMajorField]: value, [this.deKeyField]: valueItems[index] });
        });
      }
      return curValue;
    },
  },
  methods: {
    /**
     * 公共参数处理
     *
     * @param {*} arg
     * @memberof AppDataPicker
     */
    handlePublicParams(arg: any) {
      // 合并表单参数
      arg.viewParam = this.viewParam ? Util.deepCopy(this.viewParam) : {};
      arg.context = this.context ? Util.deepCopy(this.context) : {};
      // 附加参数处理
      if (this.localContext && Object.keys(this.localContext).length > 0) {
        const _context = Util.computedNavData(this.contextData, arg.context, arg.viewParam, this.localContext);
        Object.assign(arg.context, _context);
      }
      if (this.localParam && Object.keys(this.localParam).length > 0) {
        const _param = Util.computedNavData(this.contextData, arg.context, arg.viewParam, this.localParam);
        Object.assign(arg.viewParam, _param);
      }
    },

    /**
     * 打开选择视图
     *
     * @memberof AppDataPicker
     */
    openPickUpView() {
      if (this.disabled || this.readonly) {
        return;
      }
      // 公共参数处理
      const data: any = {};
      this.handlePublicParams(data);
      // 参数处理
      const view: any = this.pickUpView;
      if (!view) {
        App.getNoticeService().error(`${(this as any).$tl('common.datapicker.nopickupview', '没有配置选择视图')}`);
        return;
      }
      const _context = data.context;
      let _param = data.viewParam;
      _param = Object.assign(_param, { selectedData: [...this.curValue] });
      // 判断打开方式
      if (view?.openMode == 'POPUPMODAL') {
        this.openPopupModal(view, _context, _param);
      } else {
        this.openDrawer(view, _context, _param);
      }
    },

    /**
     * 打开链接视图
     *
     * @memberof AppPicker
     */
    openLinkView(): void {
      if (!this.contextData || !this.valueItem || !this.contextData[this.valueItem]) {
        return;
      }
      // 公共参数处理
      const data: any = {};
      this.handlePublicParams(data);
      // 参数处理
      const view: any = this.linkView;
      if (!view) {
        App.getNoticeService().error(`${(this as any).$tl('common.datapicker.nolinkview', '没有配置链接视图')}`);
        return;
      }
      const _context = data.context;
      const _param = data.viewParam;
      Object.assign(_context, { [this.deKeyField]: this.contextData[this.valueItem] });
      if (view?.openMode == 'POPUPMODAL') {
        this.openPopupModal(view, _context, _param);
      } else {
        this.openDrawer(view, _context, _param);
      }
    },

    /**
     * 模态打开
     *
     * @param view 视图模型
     * @param context 上下文
     * @param viewParam 视图参数
     * @memberof AppDataPicker
     */
    openPopupModal(view: any, context: any, viewParam: any) {
      const customStyle = {};
      if (this.dropdownViewHeight) {
        Object.assign(customStyle, {
          transform: `translateY(calc(100% - ${Util.calcBoxSize(Number(this.dropdownViewHeight))}))`,
        });
      }
      const container: Subject<any> = App.getOpenViewService().openModal(
        { viewModel: view, customStyle: customStyle },
        context,
        viewParam,
      );
      container.subscribe((result: any) => {
        if (!result || !Object.is(result.ret, 'OK')) {
          return;
        }
        this.openViewClose(result.datas);
      });
    },

    /**
     * 抽屉打开
     *
     * @param view 视图模型
     * @param context 上下文
     * @param viewParam 视图参数
     * @memberof AppDataPicker
     */
    openDrawer(view: any, context: any, viewParam: any) {
      const customStyle = {};
      if (this.dropdownViewWidght) {
        Object.assign(customStyle, { '--width': Util.calcBoxSize(Number(this.dropdownViewWidght)) });
      }
      const container: Subject<any> = App.getOpenViewService().openDrawer(
        { viewModel: view, customStyle: customStyle },
        context,
        viewParam,
      );
      container.subscribe((result: any) => {
        if (!result || !Object.is(result.ret, 'OK')) {
          return;
        }
        this.openViewClose(result.datas);
      });
    },

    /**
     * 视图关闭
     *
     * @param selects 选中数据集
     * @memberof AppDataPicker
     */
    openViewClose(selects: any[]) {
      const values: any[] = [];
      const valueItems: any[] = [];
      if (selects.length > 0) {
        selects.forEach((select: any) => {
          values.push(select[this.deMajorField]);
          valueItems.push(select[this.deKeyField]);
        });
      }
      if (this.name) {
        this.$emit('editorValueChange', { name: this.name, value: values.join(',') });
      }
      if (this.valueItem) {
        this.$emit('editorValueChange', { name: this.valueItem, value: valueItems.join(',') });
      }
    },

    /**
     * 清空
     *
     * @memberof AppDataPicker
     */
    onClear() {
      if (this.name) {
        this.$emit('editorValueChange', { name: this.name, value: null });
      }
      if (this.valueItem) {
        this.$emit('editorValueChange', { name: this.valueItem, value: null });
      }
    },

    renderICons() {
      if (this.disabled || this.readonly) {
        return null;
      }
      return this.curValue?.length > 0 ? (
        <app-icon name='close' onClick={() => throttle(this.onClear, [], this)}></app-icon>
      ) : (
        [
          <app-icon name='search' onClick={() => throttle(this.openPickUpView, [], this)}></app-icon>,
          this.linkView ? (
            <app-icon name='open' onClick={() => throttle(this.openLinkView, [], this)}></app-icon>
          ) : null,
        ]
      );
    },
  },

  render() {
    return (
      <div class='app-data-picker'>
        <ion-input
          readonly
          value={this.value}
          disabled={this.disabled}
          placeholder={this.placeholder}
          onClick={() => throttle(this.openPickUpView, [], this)}
        ></ion-input>
        {this.renderICons()}
      </div>
    );
  },
});
